/*
-------------------------------------------------

	UI.cpp

	Dmitriy Kuzmenko (Dgut)

-------------------------------------------------
*/

#include "UI.h"
#include "Common.h"
#include "Input.h"
#include "Render.h"
#include <stdarg.h>

using namespace std;

namespace Autumn
{

/*
-------------------------------------------------

	UI

-------------------------------------------------
*/

UI::UI( void ) :
	newScreen	( 0 ),
	screen		( 0 )
{
}

UI::~UI( void )
{
}

const bool UI::Init( void )
{
	return true;
}

void UI::Shutdown( void )
{
}

void UI::Frame( void )
{
	if( newScreen )
		if( !screen || screen->IsBlur() )
		{
			screen = newScreen;
			screen->Focus();
			newScreen = 0;
		}

	gRender.SetOrthogonalProjection( gCommon.WIDTH, gCommon.HEIGHT );

	screen->Frame();
	screen->Draw();
}

Screen * const UI::GetScreen( void ) const
{
	return newScreen ? newScreen : screen;
}

void UI::SetScreen( Screen * screen )
{
	newScreen = screen;
	if( UI::screen )
		UI::screen->Blur();
}

/*
-------------------------------------------------

	Screen

-------------------------------------------------
*/

Screen::Screen( void )
{
}

Screen::~Screen( void )
{
	for( list< Control * >::iterator i = controls.begin(); i != controls.end(); i++ )
		delete *i;
}
	
void Screen::Frame( void )
{
	for( list< Control * >::iterator i = controls.begin(); i != controls.end(); i++ )
		( *i )->Frame();
}

void Screen::Draw( void ) const
{
	for( list< Control * >::const_iterator i = controls.begin(); i != controls.end(); i++ )
		( *i )->Draw();
}

void Screen::AddControl( Control * control )
{
	controls.push_back( control );
}

void Screen::Focus( void )
{
}

void Screen::Blur( void )
{
}

const bool Screen::IsBlur( void )
{
	return true;
}

/*
-------------------------------------------------

	Control

-------------------------------------------------
*/

Control::Control( HorizontalAlign ha, VerticalAlign va, float x, float y, float width, float height ) :
	ha		( ha ),
	va		( va ),
	x		( x ),
	y		( y ),
	width	( width ),
	height	( height ),
	down	( false ),
	move	( false ),
	up		( false )
{
}

Control::~Control( void )
{
}

void Control::Frame( void )
{
	down = gInput.IsDown( GetGlobalX(), GetGlobalY(), width, height );
	move = gInput.IsMove( GetGlobalX(), GetGlobalY(), width, height );
	up = gInput.IsUp( GetGlobalX(), GetGlobalY(), width, height );
}

void Control::Draw( void ) const
{
}

void Control::SetVisible( bool visible )
{
	Control::visible = visible;
}

const bool Control::IsVisible( void ) const
{
	return visible;
}

const bool Control::IsDown( void ) const
{
	return down;//gInput.IsDown( GetGlobalX(), GetGlobalY(), width, height );
}

const bool Control::IsMove( void ) const
{
	return move;//gInput.IsMove( GetGlobalX(), GetGlobalY(), width, height );
}

const bool Control::IsUp( void ) const
{
	return up;//gInput.IsUp( GetGlobalX(), GetGlobalY(), width, height );
}

const float Control::GetGlobalX( void ) const
{
	float x = Control::x;

	if( ha == CENTER )
		x -= width / 2.f;
	else if( ha == RIGHT )
		x -= width;

	return x;
}

const float Control::GetGlobalY( void ) const
{
	float y = Control::y;

	if( va == MIDDLE )
		y -= height / 2.f;
	else if( va == TOP )
		y -= height;

	return y;
}

const float Control::Width( void ) const
{
	return width;
}

const float Control::Height( void ) const
{
	return height;
}

/*
-------------------------------------------------

	Label

-------------------------------------------------
*/

Label::Label( HorizontalAlign ha, VerticalAlign va, float x, float y, float width, float height, const char * text ) :
	Control	( ha, va, x, y, width, height )
{
	strcpy( Label::text, text );
}

Label::~Label( void )
{
}

void Label::SetText( const char * text, ... )
{
	va_list	arg;
	
	va_start( arg, text );
	vsnprintf( Label::text, sizeof( Label::text ), text, arg );
	va_end( arg );
}

const char * const Label::Text( void ) const
{
	return text;
}

/*
-------------------------------------------------

	Button

-------------------------------------------------
*/

Button::Button( HorizontalAlign ha, VerticalAlign va, float x, float y, float width, float height, void ( * action )( void ) ) :
	Control	( ha, va, x, y, width, height ),
	action	( action )
{
}

Button::~Button( void )
{
}

void Button::Frame( void )
{
	Control::Frame();

	if( !IsVisible() )
		return;

	if( IsUp() && action )
		action();
}

/*
-------------------------------------------------

	TextButton

-------------------------------------------------
*/

/*TextButton::TextButton( HorizontalAlign ha, VerticalAlign va, float x, float y, float width, float height, const char * text, void ( * action )( void ) ) :
	Label	( ha, va, x, y, width, height, text ),
	Button	( ha, va, x, y, width, height, action ),
	action	( action )
{
}

TextButton::~TextButton( void )
{
}*/

}	// namespace Autumn